import { asyncRoutes, constantRoutes } from '@/router'
import Layout from '@/layout'
import { getAuthMenu } from '@/api/user'
import store from '@/store'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

function _import(str) {
  return function(resolve) {
    require([`@/views/${str}.vue`], resolve)
  }
}

function _importT(str) {
    try{
      require(`@/views/${str}.vue`);
    }catch (e){
      return false;
    }
    return true;
}

export const loadView = (view) => {
  return (resolve) => require([`@/${view}.vue`], resolve)
}

export function generaMenu(routes, data,ischild = false,permissions = []) {
  data.forEach(item => {
    if (item.child && item.child.length > 0) {
      var menu = {
        path: '/' + item.module,
        component: Layout,
        name: item.module,
        meta: {
          title: item.title,
          icon: item.icon
        },
        hidden: item.type == 3?true:false,
        children: []
      }
      generaMenu(menu.children, item.child,true,permissions);
    } else {
      if(ischild){
        var viewExists = _importT(item.view);
        if(!viewExists){
          return;
        }
        permissions.push(item.module + '/' + item.action)
        var menu = {
          path: '/' + item.module + '/' + item.action,
          component: _import(item.view),
          name: 'Page' + item.module + item.action,
          meta: {
            title: item.title,
            icon: item.icon
          },
          hidden: item.type == 3?true:false
        }
      }else{
        var viewExists = _importT(item.view);
        if(!viewExists){
          return;
        }
        permissions.push(item.module + '/' + item.action)
        var menu = {
          path: '/' + item.module,
          component: Layout,
          redirect: '/' + item.module + '/' + item.action,
          name: item.module,
          meta: {
            title: item.title,
            icon: item.icon
          },
          hidden: item.type == 3?true:false,
          children: [
            {
              path: item.action,
              component: _import(item.view),
              name: 'Page' + item.module + item.action,
              meta: {
                title: item.module + item.action,
                icon: item.icon
              }
            }
          ]
        }
      }
    }
    routes.push(menu);
  })

  store.dispatch('user/setUserPermissions', permissions).then(() => {
  }).catch(() => {
  })
   //routes.push();
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    state.addRoutes = [];
    state.routes = [];
    return new Promise(resolve => {
      getAuthMenu(state.token).then(response => {
        const loadMenuData = []
        let data = response
        if (response.code !== 0) {
          this.$message({ message: '菜单数据加载异常', type: 0 })
        } else {
          data = response.data
          Object.assign(loadMenuData, data)
          var asyncRoute = asyncRoutes;
          if(asyncRoutes.length > 1){
            asyncRoute = asyncRoutes.slice(0,1);
          }
          generaMenu(asyncRoute, loadMenuData)
          let accessedRoutes = []
          let accessedRoutes_tmp = [];
          let routerObj = {}
          if (roles.includes('admin')) {
            // alert(JSON.stringify(asyncRoutes))
            accessedRoutes_tmp = asyncRoute || []
            accessedRoutes_tmp.forEach((item) => {
              if (!routerObj[item.name]) {
                if(item.hasOwnProperty('children') && item.children.length == 0){
                  return;
                }
                accessedRoutes.push(item)
                routerObj[item.name] = true
              }
            })
          } else {
            accessedRoutes_tmp = asyncRoute || []
            let resultRoute = [];
            accessedRoutes_tmp.forEach((item) => {
              if (!routerObj[item.name]) {
                if(item.hasOwnProperty('children') && item.children.length == 0){
                  return;
                }
                resultRoute.push(item)
                routerObj[item.name] = true
              }
            })
            accessedRoutes = filterAsyncRoutes(resultRoute, roles)
          }
          commit('SET_ROUTES', accessedRoutes)
          console.log(accessedRoutes);
          resolve(accessedRoutes)
        }
      }).catch(error => {
        console.log(error)
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
